﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Diagnostics;

namespace csMonitor
{
    public partial class frmMonitor : Form
    {
        public frmMonitor()
        {
            InitializeComponent();
        }

        private Timer _tmr;
        private List<Icon> _icons;

        private void Form1_Load(object sender, EventArgs e)
        {
            //MessageBox.Show(freemem.ToString()       + Environment.NewLine + 
            //               (freemem/1024).ToString() + Environment.NewLine + 
            //               (freemem*100/GetTotalMemoryInBytes()).ToString());

            _icons = new List<Icon>(101);
            for (int i = 0; i <= 100; i++)
            {
                _icons.Add(getIcon((float)i / 100, _getLevel(i)));
            }

            for (int i = 100; i >= 0; i--)
            {
                notifyIcon1.Icon = _icons[i];
                this.Icon        = _icons[i];
                Application.DoEvents();
                System.Threading.Thread.Sleep(10);
            }

            _tmr = new Timer();
            _tmr.Interval = 500;
            _tmr.Tick += new EventHandler(_tmr_Tick);
            _tmr.Enabled = true;
            this.Visible = false;

        }

        void _tmr_Tick(object sender, EventArgs e)
        {
            try
            {
                PerformanceCounter pc = new PerformanceCounter("Memory", "Available Bytes");
                ulong freemem = Convert.ToUInt64(pc.NextValue());
                ulong total   = GetTotalMemoryInBytes();
                ulong used    = total - freemem;
                float percent = (float)used / (float)GetTotalMemoryInBytes();
                //Icon  ico     =  getIcon(percent,_getLevel(percent));
                Icon ico = _icons[(int)(percent * 100)];
                notifyIcon1.Icon = ico;
                notifyIcon1.Text = percent.ToString("P1");
                this.Icon = ico;
            }
            catch (Exception ex)
            {
                //todo baloon error
                notifyIcon1.BalloonTipTitle = "Exception";
                notifyIcon1.BalloonTipText = ex.Message;
                notifyIcon1.ShowBalloonTip(5000);
            }
        }

        Color _getLevel(float percent)
        {
            return (_getLevel((int)(percent * 100)));
        }

        Color _getLevel(int percent)
        {
            if (percent >= 90)
                return Color.Red;
            else if (percent >= 80)
                return Color.Orange;
            else if (percent >= 70)
                return Color.Yellow;
            else if (percent >= 60)
                return Color.YellowGreen;
            else
                return Color.Green;
        }

        static ulong GetTotalMemoryInBytes()
        {
            return new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory;
        }

        private Icon getIcon(float percent, Color color)
        {
            //http://www.codeproject.com/Articles/7122/Dynamically-Generating-Icons-safely
            
            percent = (1-percent) * 16;
            Bitmap bmp = new Bitmap( 16 , 16 , System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(color);
                g.FillRectangle(new SolidBrush( Color.Black ), 0, 0, 16, percent); 
                g.FillRectangle(Brushes.Blue, 0, 15, 1, 1); //Fill transparency pixel  (The pixel in the lower left corner (0, 15) is used to determine the transparency color)

                // Nice example of an error icon
                //g.FillEllipse(Brushes.Red, 0, 0, 16, 16);
                //g.FillRectangle(Brushes.White, 4, 6, 8, 4);
            }
            return FlimFlan.IconEncoder.Converter.BitmapToIcon(bmp);
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
        }

        private void frmMonitor_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Visible = false;
            }
        }

//http://www.developerfusion.com/article/84486/mastering-the-system-tray/
//Draw your own icon

//Although not needed for this application, a more general solution to updating a system tray icon is to create the new icon programmatically. This allows the icon to represent more complex information, such as a graph (as used in Task Manager). To draw your own icon at runtime, you must first create a suitable Bitmap object:
//Bitmap b = new Bitmap( 16 , 16 );
//Then obtain a Graphics object with which to actually carry out drawing operations – here I show how to draw a simple circle on a transparent background:
//Graphics g = Graphics.FromImage( b );
//g.Clear( Color.Transparent );
//SolidBrush sb = new
//    SolidBrush( Color.Red );
//g.FillEllipse( sb , 0 , 0 , 16 , 16 );
//Once drawing is complete, the final step is to convert the bitmap to an icon for display. Somewhat confusingly, this is accomplished by getting an icon handle from the Bitmap object, then creating an Icon object using the static FromHandle member function:
//notifyIcon.Icon = Icon.FromHandle(
//    b.GetHicon() );

    }
}
